<template>
  <div class="chat-room-server">
    <div :class="`chat-wrap chat-theme-${theme}`" :style="{ width, height }">
      <div class="chat-head">
        <img
          class="chat-logo"
          src="../../assets/images/chat-logo.svg"
          alt=""
        />
      </div>
      <div class="chat-box">
        <div class="user-list chat-scrollbar">
          <div
            class="user-list-item"
            :class="{ 'user-item-active': userItem && userItem.userId === item.userId }"
            v-for="(item, i) in userList"
            :key="i"
            @click="handleUserChat(item)"
          >
            <span class="user-avatar">
              <img class="user-avatar-img" :src="item.avatar" alt="" />
              <template
                v-if="!(userItem && userItem.userId === item.userId) && item.unRead"
              >
                <span class="un-read-msg juzhong" v-if="item.unRead < 100">{{
                  item.unRead
                }}</span>
                <span class="un-read-more" v-else></span>
              </template>
            </span>
            <span class="user-chat-info">
              <p class="user-name">客户_{{ item.name }}</p>
              <p class="user-msg">{{ item.msg }}</p>
              <span class="user-chat-time">{{ item.time }}</span>
            </span>
          </div>
          <el-empty
            v-show="!userList.length"
            :image="require('../../assets/images/chat-empty.svg')"
            :image-size="120"
            description="暂无数据"
          ></el-empty>
        </div>
        <div class="user-chat-main">
          <div class="user-chat-1" v-show="userItem">
            <div class="chat-main">
              <div ref="chatDom" class="chat-left chat-list chat-scrollbar">
                <div class="chat-server-wrap juzhong">
                  <span class="chat-server">
                    <span class="svc-name"
                      >您正在服务&nbsp;客户_{{ userItem && userItem.name }}</span
                    >
                  </span>
                  <i
                    class="el-icon-headset"
                    :class="{ 'server-active': userType === 'server' }"
                    title="关闭人工客服"
                    @click="handleCloseServer"
                  ></i>
                </div>
                <template v-for="(item, i) in chatList">
                  <div v-if="item.type === 1" :key="i" class="chat-item chat-item-0">
                    <img class="svc-avatar" :src="item.avatar" alt="" />
                    <div>
                      <p class="service-nickname">
                        客户_{{ item.name }}&nbsp;&nbsp;{{ item.time }}
                      </p>
                      <p class="say-con" v-html="item.msg"></p>
                    </div>
                  </div>
                  <div v-if="item.type === 0" :key="i" class="chat-item chat-item-1">
                    <p class="service-nickname">您&nbsp;&nbsp;{{ item.time }}</p>
                    <p class="say-con" v-html="item.msg"></p>
                  </div>
                </template>
              </div>
              <div class="chat-right">
                <div class="server-tab juzhong">
                  <span
                    class="juzhong"
                    :class="{ 'server-tab-active': tabIndex === i }"
                    v-for="(item, i) in tabs"
                    :key="i"
                    @click="tabIndex = i"
                    >{{ item.name }}</span
                  >
                </div>
                <div class="fast-reply chat-scrollbar" v-show="tabIndex === 0">
                  <el-collapse v-model="activeName" accordion>
                    <el-collapse-item
                      :title="item.Title"
                      :name="`${i}`"
                      v-for="(item, i) in fastReplyList"
                      :key="i"
                    >
                      <p
                        class="fast-rely-item"
                        v-for="(sub, n) in item.SonItem"
                        :key="n"
                        @click="handleSetFastReply(sub.Title)"
                      >
                        {{ sub.Title }}
                      </p>
                    </el-collapse-item>
                  </el-collapse>
                </div>
                <div class="server-info juzhong" v-show="tabIndex === 1">
                  <img class="server-avatar" :src="userInfo.avatar" alt="" />
                  <p v-if="userItem">客户号：{{ userItem.userId }}</p>
                </div>
              </div>
            </div>
            <div class="chat-foot">
              <div class="chat-left">
                <div
                  ref="chatIpt"
                  class="chat-input chat-scrollbar"
                  contenteditable
                  placeholder=" 请输入你的内容..."
                ></div>
                <div class="chat-input-send">
                  <i
                    class="el-icon-phone"
                    :class="{ 'server-active': userType === 'server' }"
                    title="音视频通话"
                    @click="handleCloseServer"
                  ></i>
                  <span class="chat-send-btn juzhong" @click="handleSend">发送</span>
                </div>
              </div>
              <div class="chat-right chat-banner">
                <el-carousel height="150px">
                  <el-carousel-item v-for="(item, i) in imgTabs" :key="i">
                    <div class="swiper-slide" @click="handleImgTo(item)">
                      <span class="banner-name">{{ item.name }}</span>
                      <img class="swiper-img" :src="item.img" alt="" />
                    </div>
                  </el-carousel-item>
                </el-carousel>
              </div>
            </div>
          </div>
          <el-empty
            v-show="!userItem"
            :image="require('../../assets/images/chat-empty.svg')"
            :image-size="120"
            description="暂无数据"
          ></el-empty>
        </div>
      </div>
    </div>
  </div>
</template>
<script>
import fastReply from "./fastRely";

export default {
  name: "ServerChatSystem",
  props: {
    theme: {
      type: String,
      default: 'dark'
    },
    width: {
      type: String,
      default: '1010px'
    },
    height: {
      type: String,
      default: '600px'
    },
  },
  data() {
    return {
      userItem: null,
      userObj: {},
      userList: [
        // { name: '张三', avatar: 'https://s2.loli.net/2022/07/27/XAWVKygCPtDlIBU.png', unRead: 13, msg: '水力发电就撒娇是老师发水力发电就撒娇是老师发水力发电就撒娇是老师发', time: '14:33:33' },
      ],
      fastReplyList: fastReply,
      tabs: [{ name: "快捷回复" }, { name: "客户信息" }],
      tabIndex: 0,
      activeName: "",
      userType: "server",
      userInfo: {
        name: "客户",
        phone: "15858194070",
        avatar: 'http://10.50.101.20:90/imgs/user-avatar.png',
      },
      ws: null,
      imgTabs: [
        {
          img: require("../../assets/images/about-banner.svg"),
          link: "https://www.adayun.com/#/about",
          name: "关于我们",
        },
        {
          img: require("../../assets/images/honor-banner.png"),
          link: "https://www.adayun.com/#/honor",
          name: "荣誉资质",
        },
        {
          img: require("../../assets/images/joins.png"),
          link: "https://www.adayun.com/#/joinUs",
          name: "加入我们",
        },
      ],
      chatList: [],
      userId: "0",
    };
  },
  mounted() {
    this.initWebSocket();
    this.enterKeyup();
  },
  destroyed() {
    this.enterKeyupDestroyed();
    this.ws.close();
  },
  methods: {
    handleUserChat(item) {
      if (this.userItem && this.userItem.userId === item.userId) {
        return;
      }
      // 该聊天消息已读
      item.unRead = 0;
      this.ws.send(JSON.stringify({ unRead: 0, userId: item.userId }));
      this.userItem = item;
      this.chatList = item.chatList;
      this.scrollToBottom();
    },
    handleCloseServer() {
      this.ws.send(
        JSON.stringify({
          userType: "server",
          to: this.userItem && this.userItem.userId,
          isServer: true,
          closeServer: true,
          msg: "感谢您的咨询，再见！",
        })
      );
    },
    initWebSocket() {
      //判断页面有没有存在websocket连接
      if (window.WebSocket) {
        // 8181 端口号 要与后端配置的一致
        const url = "ws://127.0.0.1:8181?userId=" + this.userId;
        const ws = new WebSocket(url);
        ws.onopen = (e) => {
          console.log("服务器连接成功");
        };
        ws.onclose = (e) => {
          console.log("服务器连接关闭");
        };
        ws.onerror = () => {
          console.log("服务器连接出错");
        };
        ws.onmessage = (e) => {
          //接收服务器返回的数据
          const res = JSON.parse(e.data);
          if (res.userType !== "server") {
            return;
          }
          // 客服发送消息
          if (res.from === this.userId) {
            this.setUserList(res, res.to);
          }
          // 不存在聊天组时
          if (!this.userObj[res.from]) {
            this.userObj[res.from] = true;
            if (res.from !== this.userId) {
              this.userList.push({
                ...res,
                chatList: [res],
              });
            }
          } else {
            // 已存在聊天组时
            this.setUserList(res, res.from);
          }
          this.scrollToBottom();
        };
        this.ws = ws;
      } else {
        console.log("浏览器不支持websocket");
      }
    },
    setUserList(res, val) {
      let index = "";
      this.userList.forEach((item, i) => {
        item.chatList = item.chatList || [];
        // 发送给指定客户
        if (item.userId === val) {
          item.chatList.push(res);
          index = i;
        }
      });
      if (index || index === 0) {
        const row = this.userList[index];
        const item = res.isServer ? { ...row, msg: res.msg } : { ...row, ...res };
        // 该聊天消息已读
        if (this.userItem && this.userItem.userId === item.userId) {
          item.unRead = 0;
          this.ws.send(JSON.stringify({ unRead: 0, userId: item.userId }));
        }
        this.userList[index] = item;
        this.$forceUpdate();
      }
    },
    enterKey(e) {
      const code = e.keyCode ? e.keyCode : e.which ? e.which : e.charCode;
      if (!e.shiftKey && code === 13) {
        this.handleSend();
        e.preventDefault();
        return false;
      }
    },
    enterKeyupDestroyed() {
      document.removeEventListener("keydown", this.enterKey);
    },
    enterKeyup() {
      document.addEventListener("keydown", this.enterKey);
    },
    scrollToBottom() {
      const el = this.$refs.chatDom;
      this.$nextTick(() => {
        if (el) {
          el.scrollTop = el.scrollHeight;
        }
      });
    },
    handleSetFastReply(msg) {
      const params = {
        userType: "server",
        isServer: true,
        msg,
        to: this.userItem && this.userItem.userId,
      };
      this.ws.send(JSON.stringify(params));
    },
    handleSend() {
      const el = this.$refs.chatIpt;
      const msg = el.innerHTML;
      if (!msg) {
        return;
      }
      const params = {
        userType: "server",
        isServer: true,
        msg,
        userId: this.userId,
        to: this.userItem && this.userItem.userId,
      };
      this.ws.send(JSON.stringify(params));
      el.innerHTML = "";
    },
    handleImgTo(item) {
      window.open(item.link);
    },
  },
};
</script>
<style lang="less">
@import "../../assets/style/scrollbar.less";
.chat-room-server {
  display: flex;
  align-items: center;
  justify-content: center;
  // navy 天蓝色
  .chat-theme-navy {
    .chat-head, .chat-item-1 .say-con, .chat-send-btn {
      background: #409EFF !important;
    }
    .server-active, .server-tab-active {
      color: #409EFF !important;
    }
  }
  // 橘黄色
  .chat-theme-orange {
    .chat-head, .chat-item-1 .say-con, .chat-send-btn {
      background: #fd9355 !important;
    }
    .server-active, .server-tab-active {
      color: #fd9355 !important;
    }
  }
  // 暗黑色
  .chat-theme-dark {
    .chat-head, .chat-item-1 .say-con, .chat-send-btn {
      background: #303133 !important;
    }
    .server-active, .server-tab-active {
      color: #303133 !important;
    }
  }
  .el-carousel__indicators {
    white-space: nowrap;
  }
  .el-carousel__container {
    height: 100%;
  }
  .el-carousel {
    width: 100%;
  }
  .user-item-active {
    background: #eee;
  }
  .chat-box {
    flex: 1;
    display: flex;
    .user-avatar {
      position: relative;
      width: 36px;
      height: 36px;
      border-radius: 3px;
    }
    .un-read-msg {
      right: -7px;
      top: -10px;
      position: absolute;
      color: #fff;
      font-size: 12px;
      width: 16px;
      height: 16px;
      border-radius: 16px;
      overflow: hidden;
      background: red;
    }
    .un-read-more {
      overflow: hidden;
      right: -4px;
      top: -8px;
      position: absolute;
      width: 10px;
      height: 10px;
      border-radius: 10px;
      background: red;
    }
    .user-list {
      padding-bottom: 8px;
      overflow-x: hidden;
      overflow-y: auto;
      height: 100%;
      width: 210px;
      border-right: 1px solid #ddd;
    }
    .user-list-item {
      cursor: pointer;
      padding: 12px 8px;
      margin-bottom: 4px;
      display: grid;
      grid-template-columns: 36px 152px;
      &:hover {
        background: #eee;
      }
    }
    .user-avatar-img {
      width: 36px;
      height: 36px;
    }
    .user-chat-info {
      padding-left: 8px;
      position: relative;
    }
    .user-chat-time {
      color: #999;
      position: absolute;
      right: 0;
      top: 2px;
    }
    .user-name {
      font-weight: bold;
      padding-bottom: 6px;
    }
    .user-msg {
      color: #999;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
    }
    .user-chat-main {
      height: 100%;
      width: calc(100% - 210px);
    }
    .user-chat-1 {
      height: 100%;
      display: flex;
      flex-direction: column;
    }
  }
  .banner-name {
    z-index: 1;
    color: #fff;
    font-size: 24px;
    position: absolute;
    transform: translate(-50%, -50%);
    top: 50%;
    left: 50%;
    font-family: monospace;
  }
  .server-active {
    color: #409EFF;
  }
  img {
    object-fit: contain;
  }
  .chat-item-1 {
    padding-left: 40px;
    text-align: right;
    .service-nickname {
      margin-bottom: 8px;
    }
    .say-con {
      text-align: justify;
      display: inline-block;
      word-wrap: break-word;
      background-color: #409EFF;
      border-radius: 16px 0 16px 16px;
      box-shadow: 0 0 5px rgb(#000, 6%);
      line-height: 20px;
      margin: 0;
      min-height: 20px;
      padding: 8px 13px;
      word-break: break-all;
      color: #fff;
    }
  }
  .chat-item-0 {
    padding-right: 40px;
    display: flex;
    .svc-avatar {
      width: 36px;
      height: 36px;
      margin-right: 12px;
    }
    .service-nickname {
      margin-bottom: 8px;
    }
    .say-con {
      text-align: justify;
      display: inline-block;
      word-wrap: break-word;
      background: #f2f2fb;
      border: 1px solid #f2f2fb;
      border-radius: 0 16px 16px 16px;
      box-shadow: 0 1px 6px 0 #cfd1d3;
      line-height: 20px;
      margin: 0;
      min-height: 20px;
      padding: 8px 13px;
      word-break: break-all;
    }
  }
  .chat-item {
    margin-bottom: 20px;
  }
  .chat-server-wrap {
    margin-bottom: 20px;
    display: flex;
    align-items: center;
    position: sticky;
    width: 100%;
    top: 0;
    .el-icon-headset {
      position: absolute;
      right: 0;
      cursor: pointer;
      font-size: 18px;
    }
  }
  .chat-server {
    height: 26px;
    padding: 5px 20px;
    background: #f2f2fb;
    border-radius: 15px;
    color: #919bb0;
    white-space: nowrap;
  }
  .chat-list {
    position: relative;
    padding: 8px;
  }
  .chat-input {
    padding: 8px;
    outline: none;
    height: 110px;
    line-height: 20px;
  }
  .chat-input-send {
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0 8px;
    .el-icon-phone {
      font-size: 20px;
      cursor: pointer;
    }
  }
  .chat-send-btn {
    background: #409EFF;
    cursor: pointer;
    width: 60px;
    height: 28px;
    color: #fff;
    border-radius: 3px;
  }
  .chat-input:empty:before {
    color: #919bb0;
    content: attr(placeholder);
  }
  .swiper-slide {
    overflow: hidden;
    height: 150px;
    cursor: pointer;
  }
  .swiper-img {
    width: 100%;
    border: none;
  }
  .juzhong {
    display: flex;
    align-items: center;
    justify-content: center;
  }
  .server-tab {
    height: 40px;
    border-bottom: 1px solid #e0e4ea;
    display: grid;
    grid-template-columns: repeat(2, 50%);
    span {
      cursor: pointer;
      height: 100%;
      border-right: 1px solid #e0e4ea;
    }
    span:last-child {
      border-right: none;
    }
    .server-tab-active {
      color: #409EFF;
      font-weight: bold;
    }
  }
  .fast-reply {
    height: 340px;
    overflow-x: hidden;
    overflow-y: auto;
    .el-collapse {
      border-top: 0;
    }
    .el-collapse-item__header {
      padding-left: 8px;
    }
    .fast-rely-item {
      cursor: pointer;
      padding: 8px;
      border-top: 1px dashed #e0e4ea;
      &:hover {
        color: #4866d6;
      }
    }
  }
  .server-info {
    height: 340px;
    flex-direction: column;
    p {
      width: 120px;
      white-space: nowrap;
      text-align: left;
      margin-bottom: 4px;
    }
    .server-avatar {
      width: 150px;
      margin-bottom: 8px;
    }
  }
  .chat-wrap {
    overflow: hidden;
    width: 1010px;
    height: 600px;
    display: flex;
    flex-direction: column;
    background: #fff;
    border-radius: 14px;
    font-size: 12px;
    box-shadow: 0 2px 20px 8px rgb(#000, 0.2);
  }
  .chat-head {
    display: flex;
    align-items: center;
    height: 70px;
    flex: none;
    background: #409EFF;
    .chat-logo {
      width: 150px;
      margin-left: 20px;
    }
  }
  .chat-main {
    flex: 1;
    display: flex;
  }
  .chat-foot {
    height: 150px;
    flex: none;
    display: flex;
    border-top: 1px solid #e0e4ea;
  }
  .chat-left {
    flex: 1;
    border-right: 1px solid #e0e4ea;
  }
  .chat-right {
    width: 210px;
  }
  .chat-banner {
    overflow: hidden;
    position: relative;
  }
  .swiper-pagination-bullets {
    position: absolute;
    text-align: center;
    z-index: 1;
  }
}
</style>
